package jiwei.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.MalformedURLException;

//referer检查，referer拦截器
public class RefererInterceptor implements HandlerInterceptor {
    Logger log = LoggerFactory.getLogger(getClass());

    private RefererProp prop;

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        if (!prop.getEnabled()) {
            return true;
        }
        //没有配置白名单域名，也不检查referer
        if (prop.getDomains() == null || prop.getDomains().size() == 0) {
            return true;
        }

        String referer = req.getHeader("referer");
        String host = req.getServerName();
        //空referer，浏览器直接访问，放行。
        if (referer == null) {
            return true;
        }

        String refererHost;
        try {
            java.net.URL url = new java.net.URL(referer);
            refererHost = url.getHost();
        } catch (MalformedURLException e) {
            // URL解析异常，也置为404
            resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
            resp.getWriter().write("非法请求，不是同源的访问。");
            resp.flushBuffer();
            return false;
        }
        //referer和host相同，同源的链接，放行。
        if (refererHost.equals(host)) {
            return true;
        }
        //referer和host不同。判断是否在白名单。referer在白名单，放行。
        if (prop.getDomains().contains(refererHost)) {
            return true;
        }

        //referer和host不同。且不在白名单。
        log.error("referer: " + referer + ", host:" + host);
        resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
        resp.getWriter().write("非法请求，不是同源的访问。referer: " + referer + ", host:" + host);
        resp.flushBuffer();
        return false;
    }

    public RefererInterceptor(RefererProp prop) {
        this.prop = prop;
    }
}
